﻿using System;
using System.Linq;
using System.Reflection;

namespace zijian666.AnyExtensions.Privates;

internal delegate bool TryParseHandler<T>(string? value, out T result);

/// <summary>
/// 帮助构建 TryParse(string, out T) 方法的委托
/// </summary>
internal static class StringParserBuilder
{
    public static TryParseHandler<T>? Build<T>()
    {
        try
        {
            var handler = typeof(T).GetMethod("TryParse", [typeof(string), typeof(T).MakeByRefType()])?.CreateDelegate(typeof(TryParseHandler<T>)) as TryParseHandler<T>;
            if (handler is not null)
            {
                return handler;
            }
            if (GenericHelper<T>.IsEnum)
            {
                var method = typeof(Enum).GetMethods().Where(x => x.Name == "TryParse" && x.GetParameters().Length == 2).FirstOrDefault();
                handler = method?.MakeGenericMethod(typeof(T)).CreateDelegate(typeof(TryParseHandler<T>)) as TryParseHandler<T>;
                if (handler is not null)
                {
                    return handler;
                }
            }
            if (GenericHelper<T>.IsNullable)
            {
                return Methods.NullableParse_Build.MakeGenericMethod(typeof(T)).Invoke(null, null) as TryParseHandler<T>;
            }
            return null;
        }
        catch
        {
            return null;
        }

    }

    public static TryParseHandler<TStruct?>? BuildNullable<TStruct>()
        where TStruct : struct
    {
        var handler = Build<TStruct>();
        if (handler is null)
        {
            return null;
        }
        return (string? value, out TStruct? result) =>
        {
            if (string.IsNullOrWhiteSpace(value))
            {
                result = null;
                return true;
            }
            if (handler(value, out var res))
            {
                result = res;
                return true;
            }
            result = null;
            return false;
        };
    }
}
